//EventEmitter模块实际上就是观察者模式的延伸 Node.js中也有此模块
class EventEmitter {
  constructor() {
    this.object = {}
  }
  //订阅
  on(type, fn) {
    if (!this.object[type]) {
      this.object[type] = []
    }
    this.object[type].push(fn)
  }
  //取消订阅
  off(type, fn) {
    if (this.object[type]) {
      this.object[type] = this.object[type].filter(v => { return v !== fn })
    }
  }
  //发布
  emit(type, ...args) {
    if (this.object[type]) {
      this.object[type].forEach(v => { v(...args) })
    }
  }
  //只订阅一次
  once(type, fn) {
    //这里需要注意 若不写成箭头函数的话需要在外部用一个值存放this 因为匿名函数的this指向window
    const onceFn = (...args) =>{
      fn(...args)
      this.off(type, onceFn)
    }
    this.on(type, onceFn)
  }
}
let jack=new EventEmitter()
let tom = {
  read: function (info) {
    console.log(info)
  }
}
jack.on("书籍",tom.read)
jack.once("体育",tom.read)
jack.emit("书籍","斗罗大陆上线了")
jack.emit("体育","皇马绝杀")
jack.emit("体育","皇马绝杀")